﻿
using Company.Shell.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using System.Windows.Controls;

namespace Company.Shell.Dialogs
{
    public class DialogService : IDialogService
    {
        /// <summary>
        /// 弹出对话框
        /// </summary>
        /// <typeparam name="TView">用户控件</typeparam>
        /// <typeparam name="TViewModel">视图模型</typeparam>
        /// <typeparam name="TResult">返回结果类型</typeparam>
        /// <param name="view">用户控件实例</param>
        /// <param name="viewModel">视图模型实例</param>
        /// <returns>对话框结果</returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<DialogResult<TResult>> ShowDialogAsync<TView, TViewModel, TResult>(TView? view = null, TViewModel? viewModel = null)
            where TView : UserControl, new()
            where TViewModel : class, new()
        {
            view ??= Activator.CreateInstance<TView>();//如果没有传入view，则创建一个新的实例
            viewModel ??= Activator.CreateInstance<TViewModel>();//如果没有传入viewModel，则创建一个新的实例
            view.DataContext = viewModel;
            DialogWindow dialogWindow = new()
            {
                View = view,
                Width = view.Width,
                Height = view.Height
            };
            var tcs = new TaskCompletionSource<DialogResult<TResult>>();//创建一个任务完成源，用于异步等待对话框结果
             dialogWindow.Closed += (s, e) =>//对话框关闭时触发
            {
                var window = s as Window;
                var dialogViewModel = viewModel as IDialogViewModel<TResult>;
                var result = new DialogResult<TResult>(dialogViewModel ?? throw new InvalidOperationException("viewModel 必须实现 IDialogViewModel<TResult>"));
                result.SetSuccess(window?.DialogResult == true);
                tcs.SetResult(result);//设置任务结果
            };
            var vm = App.Current.Services.GetService<ShellViewModel>(); //获取ShellViewModel实例
            if (vm != null)
            {
                vm.Show = Visibility.Visible;//显示遮罩层
                bool? result = dialogWindow.ShowDialog();//显示对话框，并等待用户操作
                vm.Show = Visibility.Collapsed;//隐藏遮罩层
            }
            else
            {
                bool? result = dialogWindow.ShowDialog();//显示对话框，并等待用户操作
            }
            return await tcs.Task;
        }
    }
}
